﻿using Identitymodels;
using Identitymodels.Authorization;
using Infra_Bus;
using Infra_common;
using Infra_common.Aes;
using Infra_common.YIBanUrl;
using Infra_Common.redis;
using MediatR;

using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Linq;
using System;
using xiaodingmarket_application.Interfaces;
using xiaodingmarket_application.Service;
using xiaodingmarket_Domain.CommandHandlers;
using xiaodingmarket_Domain.Commands;
using xiaodingmarket_Domain.Commands.Order;
using xiaodingmarket_Domain.Commands.Sell;
using xiaodingmarket_Domain.Commands.User;
using xiaodingmarket_Domain.EventHandlers;
using xiaodingmarket_Domain.Events.Commodity;
using xiaodingmarket_Domain.Events.Order;
using xiaodingmarket_Domain.Events.Sell;
using xiaodingmarket_Domain.Interfaces;
using xiaodingmarket_Domain.Interfaces.IRepository;
using xiaodingmarket_Domain_core.Bus;
using xiaodingmarket_Domain_core.Events;
using xiaodingmarket_Domain_core.Notificatiions;
using xiaodingmarket_Infra_Data.Context;
using xiaodingmarket_Infra_Data.Repository;
using xiaodingmarket_Infra_Data.Repository.EventStore;
using xiaodingmarket_Infra_Data.UoW;

namespace Infra_Ioc
{
    public class NativeInjectorBootStrapper
    {
        public static void RegisterServices(IServiceCollection services, IConfiguration configuration)
        {
            //redis
            var section = configuration.GetSection("Redis:Default");
            string _connectionString = section.GetSection("Connection").Value;
            string _instanceName = section.GetSection("InstanceName").Value;
            int _defaultDB = int.Parse(section.GetSection("DefaultDB").Value ?? "0");
            services.AddSingleton(new RedisClient(_connectionString, _instanceName, _defaultDB));
            //AspectCore

            // Domain Bus (Mediator)
            services.AddScoped<IMediatorHandler, InMemoryBus>();

            // ASP.NET Authorization Polices
            services.AddSingleton<IAuthorizationHandler, ClaimsRequirementHandler>();

            // Application
            services.AddScoped<redisTest>();
            services.AddScoped<ICommodityService, CommodityService>();
            services.AddScoped<IOrderService, OrderService>();
            services.AddScoped<IManageService, ManageService>();
            services.AddScoped<ISellService, SellService>();
            services.AddScoped<IUserService, UserService>();
            services.AddScoped<IRoleService, RoleService>();

            // Domain - Events
            services.AddScoped<INotificationHandler<DomainNotification>, DomainNotificationHandler>();
            services.AddScoped<INotificationHandler<CommodityCreateEvent>, CommodityEventHandler>();
            services.AddScoped<INotificationHandler<CommodityRemoveEvent>, CommodityEventHandler>();
            services.AddScoped<INotificationHandler<CommodityReviewEvent>, CommodityEventHandler>();
            services.AddScoped<INotificationHandler<CommodityUpdateEvent>, CommodityEventHandler>();
            services.AddScoped<INotificationHandler<OrderCreatEvent>, OrderEventHandler>();
            services.AddScoped<INotificationHandler<OrderRemoveEvent>, OrderEventHandler>();
            services.AddScoped<INotificationHandler<OrderUpdateEvent>, OrderEventHandler>();
            services.AddScoped<INotificationHandler<WantAndTobeFriendEvent>, SellEventHandler>();

           

            // Domain - Commands
            services.AddScoped<IRequestHandler<ReviewCommodityCommand, bool>, CommdityCommandHandler>();
            services.AddScoped<IRequestHandler<UpdateCommodityCommand, bool>, CommdityCommandHandler>();
            services.AddScoped<IRequestHandler<CreateNewCommodityCommand, bool>, CommdityCommandHandler>();
            services.AddScoped<IRequestHandler<CreateNewOrderCommand, bool>, OrderCommandHandler>();
            services.AddScoped<IRequestHandler<RemoveOrderCommand, bool>, OrderCommandHandler>();
            services.AddScoped<IRequestHandler<UpdateOrderCommand, bool>, OrderCommandHandler>();
            services.AddScoped<IRequestHandler<WantAndTobeFriendCommand, bool>, SellCommandHandler>();
            services.AddScoped<IRequestHandler<CreateUserCommand, bool>, UserCommandHandler>();
            services.AddScoped<IRequestHandler<UpdateUserCommand, bool>, UserCommandHandler>();
            services.AddScoped<IRequestHandler<RemoveUserCommand, bool>, UserCommandHandler>();
            // Infra - Data
            services.AddScoped<ICommodityRepository, CommodityRepository>();
            services.AddScoped<IOrderRepository, OrderRepository>();
            services.AddScoped<IUserRepository, UserRepository>();
            services.AddScoped<IRoleRepository, RoleRepository>();
            services.AddScoped<IUserRoleRepository, UserRoleRepository>();
            // Infra - Aes
            var Aessection = configuration.GetSection("Aes");
            string Appid = Aessection.GetSection("Appid").Value;
            string AppSecret = Aessection.GetSection("AppSecret").Value;
            services.AddSingleton(new Aes(Appid,AppSecret));
            // Infra - Common
            services.AddSingleton(new YBUrl());
            services.AddSingleton(new JwtToken());
            services.AddSingleton(new PictureManger());

            services.AddScoped<IUnitOfWork, UnitOfWork<MarketContext>>();
            services.AddScoped<MarketContext>();

            //Infra - Data EventSourcing
            services.AddScoped<IEventStoreRepository, EventStoreSqlRepository>();
            services.AddScoped<IEventStoreService, SqlEventStore>();
            services.AddScoped<EventStoreSqlContext>();

            // Infra - Identity
            services.AddScoped<IUser, AspNetUser>();
        }
    }
}

